package com.binance.mbxgateway.web.aop;

import java.lang.annotation.Annotation;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;

import com.binance.master.error.BusinessException;
import com.binance.master.error.GeneralCode;
import com.google.common.collect.Lists;

import lombok.extern.slf4j.Slf4j;

@Component
@Aspect
@Slf4j
public class MbxAspect {

    @Pointcut("execution(* com.binance.mbxgateway.web.service.impl.Matchbox*Impl.*(..))")
    public void matchboxMethodCheck() {}

    @Around("matchboxMethodCheck()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        Object[] args = point.getArgs();
        MethodSignature signature = (MethodSignature) point.getSignature();
        log.info("Will to invoke matchbox,now to validate the args.The signature is {}", signature.toLongString());
        String[] names = signature.getParameterNames();
        Annotation[][] annotations = signature.getMethod().getParameterAnnotations();

        if (names.length > 0) {
            List<String> errors = Lists.newArrayList();
            for (int i = 0; i < names.length; i++) {
                Annotation[] annotations1 = annotations[i];
                NotEmpty ne = null;
                for (Annotation annotation : annotations1) {
                    if (annotation instanceof NotEmpty) {
                        ne = (NotEmpty) annotation;
                        break;
                    }
                }
                if (ne != null) {
                    Object arg = args[i];
                    if (arg == null) {
                        errors.add("参数" + names[i] + "不能为空");
                    } else {
                        if (arg instanceof String) {
                            if (StringUtils.isBlank(arg.toString())) {
                                errors.add("参数" + names[i] + "不能为空");
                            }
                        }
                    }
                }
            }
            if (errors.size() > 0) {
                throw new BusinessException(GeneralCode.ILLEGAL_PARAM, StringUtils.join(errors.iterator(), ";"));
            }
        }
        try {
            return point.proceed();
        } catch (HttpStatusCodeException e) {
            log.warn("调用撮合失败，微服务对于接口是{}，异常信息是{}", signature.toLongString(), e.getResponseBodyAsString());
            throw e;
        } catch (Throwable e) {
            log.warn("调用撮合失败，微服务对于接口是{}，异常信息是{}", signature.toLongString(), e);
            throw e;
        }
    }
}
